#include "utils/lockfree_queue.h"
#include <gtest/gtest.h>
#include <thread>
#include <vector>
#include <chrono>
#include <queue>
#include <mutex>

using namespace hft::utils;

// 基本功能测试
TEST(LockfreeQueueTest, BasicOperations) {
    LockfreeQueue<int, 8> queue;
    
    // 初始状态检查
    EXPECT_TRUE(queue.empty());
    EXPECT_FALSE(queue.full());
    EXPECT_EQ(queue.size(), 0);
    EXPECT_EQ(queue.capacity(), 7);  // N-1 due to implementation

    // 推入元素
    EXPECT_TRUE(queue.try_push(1));
    EXPECT_FALSE(queue.empty());
    EXPECT_EQ(queue.size(), 1);

    // 弹出元素
    int value;
    EXPECT_TRUE(queue.try_pop(value));
    EXPECT_EQ(value, 1);
    EXPECT_TRUE(queue.empty());
}

// 边界条件测试
TEST(LockfreeQueueTest, BoundaryConditions) {
    LockfreeQueue<int, 4> queue;  // 实际可用容量为3

    // 填满队列
    EXPECT_TRUE(queue.try_push(1));
    EXPECT_TRUE(queue.try_push(2));
    EXPECT_TRUE(queue.try_push(3));
    EXPECT_TRUE(queue.full());
    EXPECT_FALSE(queue.try_push(4));  // 应该失败

    // 清空队列
    int value;
    EXPECT_TRUE(queue.try_pop(value));
    EXPECT_EQ(value, 1);
    EXPECT_TRUE(queue.try_pop(value));
    EXPECT_EQ(value, 2);
    EXPECT_TRUE(queue.try_pop(value));
    EXPECT_EQ(value, 3);
    EXPECT_FALSE(queue.try_pop(value));  // 应该失败
}

// 并发测试（单生产者单消费者）
TEST(LockfreeQueueTest, SPSC_Concurrency) {
    constexpr size_t QUEUE_SIZE = 1024;
    constexpr size_t NUM_OPERATIONS = 1000000;

    LockfreeQueue<int, QUEUE_SIZE> queue;
    std::atomic<bool> producer_finished{false};
    std::atomic<size_t> successful_pushes{0};
    std::atomic<size_t> successful_pops{0};
    std::atomic<size_t> failed_pushes{0};
    std::atomic<size_t> failed_pops{0};

    // 生产者线程
    std::thread producer([&]() {
        for (size_t i = 0; i < NUM_OPERATIONS; ++i) {
            while (!queue.try_push(i)) {
                failed_pushes++;
                std::this_thread::yield();
            }
            successful_pushes++;
        }
        producer_finished = true;
    });

    // 消费者线程
    std::thread consumer([&]() {
        int value;
        while (!producer_finished || !queue.empty()) {
            if (queue.try_pop(value)) {
                successful_pops++;
            } else {
                failed_pops++;
                std::this_thread::yield();
            }
        }
    });

    producer.join();
    consumer.join();

    EXPECT_EQ(successful_pushes, NUM_OPERATIONS);
    EXPECT_EQ(successful_pops, NUM_OPERATIONS);
    EXPECT_TRUE(queue.empty());

    std::cout << "Failed pushes: " << failed_pushes << std::endl;
    std::cout << "Failed pops: " << failed_pops << std::endl;
}

// 性能测试：无锁队列 vs 互斥锁保护的队列
TEST(LockfreeQueueTest, PerformanceBenchmark) {
    constexpr size_t QUEUE_SIZE = 1024;
    constexpr size_t NUM_OPERATIONS = 1000000;

    // 测试无锁队列性能
    {
        LockfreeQueue<int, QUEUE_SIZE> queue;
        auto start = std::chrono::high_resolution_clock::now();
        
        std::thread producer([&]() {
            for (size_t i = 0; i < NUM_OPERATIONS; ++i) {
                while (!queue.try_push(i)) {
                    std::this_thread::yield();
                }
            }
        });

        std::thread consumer([&]() {
            int value;
            size_t count = 0;
            while (count < NUM_OPERATIONS) {
                if (queue.try_pop(value)) {
                    count++;
                } else {
                    std::this_thread::yield();
                }
            }
        });

        producer.join();
        consumer.join();
        
        auto end = std::chrono::high_resolution_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
        std::cout << "Lock-free queue average time per operation: "
                  << duration.count() * 1.0 / NUM_OPERATIONS
                  << " us" << std::endl;
    }

    // 测试互斥锁保护的队列性能
    {
        std::queue<int> queue;
        std::mutex mutex;
        auto start = std::chrono::high_resolution_clock::now();
        
        std::thread producer([&]() {
            for (size_t i = 0; i < NUM_OPERATIONS; ++i) {
                std::lock_guard<std::mutex> lock(mutex);
                queue.push(i);
            }
        });

        std::thread consumer([&]() {
            size_t count = 0;
            while (count < NUM_OPERATIONS) {
                std::lock_guard<std::mutex> lock(mutex);
                if (!queue.empty()) {
                    queue.pop();
                    count++;
                }
            }
        });

        producer.join();
        consumer.join();
        
        auto end = std::chrono::high_resolution_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
        std::cout << "Mutex-based queue average time per operation: "
                  << duration.count() * 1.0 / NUM_OPERATIONS
                  << " us" << std::endl;
    }
}

// 可选接口测试
TEST(LockfreeQueueTest, OptionalInterface) {
    LockfreeQueue<int, 4> queue;

    // 测试try_pop()返回optional
    EXPECT_FALSE(queue.try_pop().has_value());

    queue.try_push(42);
    auto result = queue.try_pop();
    ASSERT_TRUE(result.has_value());
    EXPECT_EQ(*result, 42);
}

// 清空操作测试
TEST(LockfreeQueueTest, ClearOperation) {
    LockfreeQueue<int, 8> queue;

    // 填充一些数据
    queue.try_push(1);
    queue.try_push(2);
    queue.try_push(3);

    EXPECT_EQ(queue.size(), 3);
    queue.clear();
    EXPECT_TRUE(queue.empty());
    EXPECT_EQ(queue.size(), 0);

    // 清空后应该可以继续使用
    EXPECT_TRUE(queue.try_push(4));
    int value;
    EXPECT_TRUE(queue.try_pop(value));
    EXPECT_EQ(value, 4);
}